/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: ActivityTurntableDrawServiceImpl
 * Author:   zhouheng
 * Date:     2019/6/16 23:36
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.zhouh.golden.activity.service.impl;

import com.zhouh.golden.activity.common.ResultResp;
import com.zhouh.golden.activity.common.ReturnCodeEnum;
import com.zhouh.golden.activity.dao.ActDrawAwardItemMapper;
import com.zhouh.golden.activity.dao.ActDrawAwardMapper;
import com.zhouh.golden.activity.dao.ActDrawAwardRecordMapper;
import com.zhouh.golden.activity.domain.ActDrawAward;
import com.zhouh.golden.activity.domain.ActDrawAwardItem;
import com.zhouh.golden.activity.domain.ActDrawAwardRecord;
import com.zhouh.golden.activity.dto.ActDrawAwardRecordBean;
import com.zhouh.golden.activity.dto.ActivityTurntableDrawReq;
import com.zhouh.golden.activity.service.ActivityTurntableDrawService;
import com.zhouh.golden.activity.service.processor.ActivityDrawContext;
import com.zhouh.golden.activity.service.processor.ActivityTurntableDrawProxy;
import com.zhouh.golden.activity.service.processor.constants.DrawContants;
import com.zhouh.golden.activity.service.processor.exception.RewardException;
import com.zhouh.golden.activity.util.RedisManager;
import com.zhouh.golden.system.dao.UserMapper;
import com.zhouh.golden.system.domain.MyUser;
import com.zhouh.golden.system.dto.UserQueryRequest;
import com.zhouh.golden.system.dto.UserQueryResponse;
import com.zhouh.golden.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.base.select.SelectByPrimaryKeyMapper;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.zhouh.golden.activity.service.processor.constants.DrawContants.DRAW_AWARD;
import static com.zhouh.golden.activity.util.RedisManager.getAwardRedisKey;

/**
 * 〈一句话功能简述〉<br> 
 * 〈〉
 *
 * @author zhouheng
 * @create 2019/6/16
 * @since 1.0.0
 */
@Slf4j
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class ActivityTurntableDrawServiceImpl implements ActivityTurntableDrawService {

    @Autowired
    private ActivityTurntableDrawProxy activityTurntableDrawProxy;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ActDrawAwardItemMapper actDrawAwardItemMapper;
    @Autowired
    private ActDrawAwardMapper actDrawAwardMapper;

    @Autowired
    private ActDrawAwardRecordMapper actDrawAwardRecordMapper;
    @Autowired
    private UserService userService;

    /**
     * @description: 奖池初始化
     * @date: 2019/6/16 23:41
     * @author:zhouheng
     */
    @PostConstruct
    public void init(){
        log.info("开始初始化奖品数据");

        //获得所有奖项：一等奖、二等奖、三等奖..
        List<ActDrawAwardItem> awardItems = this.actDrawAwardItemMapper.queryAwardItem();
//        List<ActDrawAwardRecord> records = this.actDrawAwardRecordMapper.selectAll();

        if(CollectionUtils.isEmpty(awardItems)){
//            throw new Exception("奖品数据未创建，初始化失败");
        }
        // 将抽奖奖项放入缓存中
        redisTemplate.opsForValue().set(DrawContants.DRAW_ITEM,awardItems);
        redisTemplate.expire(DrawContants.DRAW_ITEM,DrawContants.EXPIRE_TIME, TimeUnit.DAYS);

        // 抽奖奖项对应的奖品放入缓存中
        for (ActDrawAwardItem actDrawAwardItem: awardItems){
            // 根据奖项获取奖品信息

            ActDrawAward actDrawAward = actDrawAwardMapper.queryAwardById(actDrawAwardItem.getAwardId());
            redisTemplate.opsForValue().set(getAwardRedisKey(actDrawAward),actDrawAward);
            redisTemplate.expire(getAwardRedisKey(actDrawAward),DrawContants.EXPIRE_TIME, TimeUnit.DAYS);
            // TODO 如果奖品是有数量限制的，比如京东券 ，那么针对这类的奖品需要放到队列中
            // redisTemplate.opsForList().leftPush()
        }
    }


    @Override
    public ResultResp<ActDrawAwardRecordBean> draw(ActivityTurntableDrawReq activityTurntableDrawReq) {
        ResultResp<ActDrawAwardRecordBean> recordBeanResultResp=new ResultResp<ActDrawAwardRecordBean>();

        try{
            // 1 检查请求参数，校验当前用户抽奖是否证在进行
            checkDrawParams(activityTurntableDrawReq);
            // 2 抽奖
            ActivityDrawContext activityDrawContext = new ActivityDrawContext();
            activityDrawContext.setActivityTurntableDrawReq(activityTurntableDrawReq);

            UserQueryRequest userQueryRequest = new UserQueryRequest();
            userQueryRequest.setUserId(activityTurntableDrawReq.getUserId());

            // 获取用户信息
            UserQueryResponse userQueryResponse = userService.getUserById(userQueryRequest);
            activityDrawContext.setUserQueryResponse(userQueryResponse);

            activityTurntableDrawProxy.doDrawForProxy(activityDrawContext);

            ActDrawAwardRecordBean actDrawAwardRecordBean = new ActDrawAwardRecordBean();
            actDrawAwardRecordBean.setLevel(activityDrawContext.getActDrawAwardItem().getLevel());
            actDrawAwardRecordBean.setName(activityDrawContext.getUserQueryResponse().getUsername());
            actDrawAwardRecordBean.setUserId(activityDrawContext.getActivityTurntableDrawReq().getUserId());

            //设置返回的信息
            recordBeanResultResp.setResult(actDrawAwardRecordBean);
            recordBeanResultResp.setReturnCodeEnum(ReturnCodeEnum.SUCCESS);
        }catch (Exception e) {
            log.error("抽奖失败!", e);
            recordBeanResultResp.setReturnCodeEnum(ReturnCodeEnum.SYSTEM_ERROR);
        } finally {
            log.info("抽奖请求{},响应{}", activityTurntableDrawReq, recordBeanResultResp);
            //清除正在抽奖标志cache
            cleanRedisCache(activityTurntableDrawReq);
        }


        return recordBeanResultResp;
    }

    /**
     * @description: 清除正在抽奖标志cache
     * @date: 2019/6/21 23:16
     * @author:zhouheng
     */
    private void cleanRedisCache(ActivityTurntableDrawReq activityTurntableDrawReq) {
        try {
            redisTemplate.delete(RedisManager.getDrawingRedisKey(activityTurntableDrawReq));
        } catch (Exception e) {
            log.error("清除key[" +RedisManager.getDrawingRedisKey(activityTurntableDrawReq)+ "]异常", e);
        }
    }

    @Override
    public Integer queryRemainDrawCount(ActivityTurntableDrawReq activityTurntableDrawReq) {
        return null;
    }

    /**
     * @description: 检查请求参数，校验当前用户抽奖是否证在进行
     * @date: 2019/6/19 23:12
     * @author:zhouheng
     */
    private void checkDrawParams(ActivityTurntableDrawReq activityTurntableDrawReq){
        if ((null == activityTurntableDrawReq.getUserId())) {
            throw new RewardException("uid不能为空");
        }
        Object value=redisTemplate.opsForValue().get(RedisManager.getDrawingRedisKey(activityTurntableDrawReq));
        if(value != null && DrawContants.ISEXIST.EXIST.getValue().equals(value)){
            throw new RewardException("上一次抽奖还未结束");
        }
        //设置正在抽奖
        redisTemplate.opsForValue().set(RedisManager.getDrawingRedisKey(activityTurntableDrawReq),DrawContants.ISEXIST.EXIST.getValue());
        redisTemplate.expire(RedisManager.getDrawingRedisKey(activityTurntableDrawReq),DrawContants.EXPIRE_TIME,TimeUnit.DAYS);
    }
}